#include "player.h"
#include "globals.h"
#include "functions.h"
#include "config.h"
#include "SDL/SDL_ttf.h"

std::map<RakNet::RakNetGUID, Player*> Player::Players;

Player::Player(RakNet::RakNetGUID guid, std::string name, int x, int y)
{
    box.x = x;
    box.y = y;
    box.w = 32;
    box.h = 32;

    Players.insert(std::pair<RakNet::RakNetGUID, Player*>(guid, this));
    this->guid = guid;
    this->name = name;
    pos.x = x;
    pos.y = y;
    flag.x = -1;
    flag.y = -1;
    velX = 0;
    velY = 0;
    dir = DIR_UP;
    //inCombat = 0;

    movementSpeed = 256;
    hp = 100;
    mp = 100;
    maxhp = 100;
    maxmp = 100;

    set_clips();
    myUF = new UnitFrame(Players.size() + 1, 0.75, 1);
    nameText = TTF_RenderText_Solid(font, name.c_str(), textColor);
}

Player::~Player()
{
    SDL_FreeSurface(nameText);

    delete myUF;
    Players.erase(this->guid);
}

Player* Player::GetPlayerFromGUID(RakNet::RakNetGUID guid)
{
    std::map<RakNet::RakNetGUID, Player*>::iterator i;
    i = Players.find(guid);

    if (i != Players.end())
        return i->second;

    return NULL;
}

std::map<RakNet::RakNetGUID, Player*> Player::GetPlayerList()
{
    return Players;
}

void Player::stop()
{
    flag.x = 0;
    flag.y = 0;

    velX = 0;
    velY = 0;
}

void Player::create_flag(int x, int y)
{

    flag.x = x;
    flag.y = y;

    //inCombat = 0;
    dir = calculate_dir(pos.x, pos.y, flag.x, flag.y);
    calculate_vel();
}

void Player::move(Uint32 deltaTicks)
{
    /*if (pos.x < 64)
    {
        //output->write("Travel west!");
        pos.x = 64;
    }

    if (pos.x + 64 > cfg.get_map_width())
    {
        //output->write("Travel east!");
        pos.x = cfg.get_map_width() - 64;
    }

    if (pos.y < 64)
    {
        //output->write("Travel north!");
        pos.y = 64;
    }

    if (pos.y + 64 > cfg.get_map_height())
    {
        //output->write("Travel south!");
        pos.y = cfg.get_map_width() - 64;
    }

    update_rect();*/

    if (flag.x != -1 && flag.y != -1)
    {
        /*if ((x + box.w / 2.f == flag.x) and (y + box.h / 2.f == flag.y))
        {
            myFlag = NULL;
        }
        else
        {
            if (x + box.w / 2.f != flag.x)
            {
                x += movementSpeed * (deltaTicks / 1000.f) * (flag.x - x - box.w / 2.f) / distance(x + box.w / 2.f, y + box.h / 2.f, flag.x, flag.y);

                if (xRatio > 1)
                {
                    if (x + box.w / 2.f > flag.x)
                    {
                        x = flag.x - box.w / 2.f;
                    }
                }
                else
                {
                    if (x + box.w / 2.f < flag.x)
                    {
                        x = flag.x - box.w / 2.f;
                    }
                }
            }

            if (touches_wall(box, tiles))
            {
                //x -= movementSpeed * (deltaTicks / 1000.f) * (flag.x - x) / distance(x, y, flag.x, flag.y) * 1.1;
            }

            if (y + box.h / 2.f != flag.y)
            {
                y += movementSpeed * (deltaTicks / 1000.f) * (flag.y - y - box.h / 2.f) / distance(x + box.w / 2.f, y + box.h / 2.f, flag.x, flag.y);

                if (yRatio > 1)
                {
                    if (y + box.w / 2.f > flag.y)
                    {
                        y = flag.y - box.h / 2.f;
                    }
                }
                else
                {
                    if (y + box.w / 2.f < flag.y)
                    {
                        y = flag.y - box.h / 2.f;
                    }
                }
            }

            if (touches_wall(box, tiles))
            {
                //y -= movementSpeed * (deltaTicks / 1000.f) * (flag.y - y) / distance(x, y, flag.x, flag.y) * 1.1;
            }

            update_rect();

        }*/

        if (pos.x != flag.x)
        {
            pos.x += (deltaTicks / 1000.f) * velX;

            if (velX > 0)
            {
                if (pos.x > flag.x)
                {
                    pos.x = flag.x;
                }
            }
            else
            {
                if (pos.x < flag.x)
                {
                    pos.x = flag.x;
                }
            }
        }

        if (pos.y != flag.y)
        {
            pos.y += (deltaTicks / 1000.f) * velY;

            if (velY > 0)
            {
                if (pos.y > flag.y)
                {
                    pos.y = flag.y;
                }
            }
            else
            {
                if (pos.y < flag.y)
                {
                    pos.y = flag.y;
                }
            }
        }

        if ((pos.x == flag.x) and (pos.y == flag.y))
        {
            stop();
        }

        update_rect();
    }
}

void Player::calculate_vel()
{
    velX = movementSpeed * (flag.x - pos.x) / distance(pos.x, pos.y, flag.x, flag.y);
    velY = movementSpeed * (flag.y - pos.y) / distance(pos.x, pos.y, flag.x, flag.y);
}

void Player::update_rect()
{
    box.x = pos.x - box.w / 2.f;
    box.y = pos.y - box.h / 2.f;
}

void Player::set_clips()
{
    //Clip the sprites

    myClip[DIR_RIGHTUP].x = box.w * 0;
    myClip[DIR_RIGHTUP].y = 0;
    myClip[DIR_RIGHTUP].w = box.w;
    myClip[DIR_RIGHTUP].h = box.h;

    myClip[DIR_RIGHT].x = box.w * 1;
    myClip[DIR_RIGHT].y = 0;
    myClip[DIR_RIGHT].w = box.w;
    myClip[DIR_RIGHT].h = box.h;

    myClip[DIR_RIGHTDOWN].x = box.w * 2;
    myClip[DIR_RIGHTDOWN].y = 0;
    myClip[DIR_RIGHTDOWN].w = box.w;
    myClip[DIR_RIGHTDOWN].h = box.h;

    myClip[DIR_DOWN].x = box.w * 3;
    myClip[DIR_DOWN].y = 0;
    myClip[DIR_DOWN].w = box.w;
    myClip[DIR_DOWN].h = box.h;

    myClip[DIR_LEFTDOWN].x = box.w * 4;
    myClip[DIR_LEFTDOWN].y = 0;
    myClip[DIR_LEFTDOWN].w = box.w;
    myClip[DIR_LEFTDOWN].h = box.h;

    myClip[DIR_LEFT].x = box.w * 5;
    myClip[DIR_LEFT].y = 0;
    myClip[DIR_LEFT].w = box.w;
    myClip[DIR_LEFT].h = box.h;

    myClip[DIR_LEFTUP].x = box.w * 6;
    myClip[DIR_LEFTUP].y = 0;
    myClip[DIR_LEFTUP].w = box.w;
    myClip[DIR_LEFTUP].h = box.h;

    myClip[DIR_UP].x = box.w * 7;
    myClip[DIR_UP].y = 0;
    myClip[DIR_UP].w = box.w;
    myClip[DIR_UP].h = box.h;
}

void Player::set_x(int dest_x)
{
    pos.x = dest_x;
    update_rect();
}

void Player::set_y(int dest_y)
{
    pos.y = dest_y;
    update_rect();
}

int Player::x()
{
    return (int)pos.x;
}

int Player::y()
{
    return (int)pos.y;
}

/*std::string Player::get_guid()
{
    return guid;
}*/

std::string Player::get_name()
{
    return name;
}

void Player::draw()
{
    apply_surface(box.x, box.y, imgPlayer, screen, &myClip[dir]);
    apply_surface(pos.x - (nameText->w * 0.5), pos.y - (nameText->h * 0.5) - box.h, nameText, screen);
    //myUF->draw();

    if (debug)
        draw_box(box.x, box.y, box.w, box.h, 0xFF0000FF, false);
}
